<div class="content-section introduction">
    <div class="feature-intro">
        <h1>MultiSelect</h1>
        <p>MultiSelect is used to multiple values from a list of options.</p>
    </div>
    <app-inputStyleSwitch></app-inputStyleSwitch>
</div>

<div class="content-section implementation">
    <div class="card">
        <h5>Basic</h5>
        <p-multiSelect [options]="cities" [(ngModel)]="selectedCities" defaultLabel="Select a City" optionLabel="name"></p-multiSelect>
    
        <h5>Templating</h5>
        <p-multiSelect [options]="countries" [(ngModel)]="selectedCountries1" defaultLabel="Select a Country" optionLabel="name" class="multiselect-custom">
            <ng-template let-value pTemplate="selectedItems">
                <div class="country-item country-item-value" *ngFor="let option of selectedCountries1">
                    <img src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + option.code.toLowerCase()" />
                    <div>{{option.name}}</div>
                </div>
                <div *ngIf="!selectedCountries1 || selectedCountries1.length === 0" class="country-placeholder">
                    Select Countries
                </div>
            </ng-template>
            <ng-template let-country pTemplate="item">
                <div class="country-item">
                    <img src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + country.value.code.toLowerCase()" />
                    <div>{{country.value.name}}</div>
                </div>
            </ng-template>
        </p-multiSelect>
    
        <h5>Virtual Scroll (10000 Items)</h5>
        <p-multiSelect [options]="items" [showToggleAll]="false" [(ngModel)]="selectedCountries2" optionLabel="name" [virtualScroll]="true" [filter]="true" [itemSize]="34" class="multiselect-custom-virtual-scroll">
            <ng-template let-country pTemplate="item">
                <div class="country-item">
                    <img src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + country.value.code.toLowerCase()" />
                    <div>{{country.value.name}}</div>
                </div>
            </ng-template>
        </p-multiSelect>
    </div>
</div>

<div class="content-section documentation">
    <p-tabView>
        <p-tabPanel header="Documentation">
            <h5>CDK</h5>
            <p>Virtual Scrolling enabled MultiSelect depends on @angular/cdk's ScrollingModule so begin with installing CDK if not already installed.</p>

<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
npm install @angular/cdk --save
</app-code>

            <h5>Import</h5>
<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
import &#123;MultiSelectModule&#125; from 'primeng/multiselect';
</app-code>

            <h5>Getting Started</h5>
            <p>MultiSelect requires a value to bind and a collection of options. There are two alternatives of how to define the <i>options</i> property; one way is providing a collection of SelectItem
            instances whereas other way is providing an array of arbitrary objects along with the <i>optionLabel</i> property to specify the field name of the option. SelectItem API is designed to have more control on how
            the options are displayed such as grouping and disabling however in most cases an arbitrary object collection will suffice. Example below demonstrates both cases.</p>
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-multiSelect [options]="cities1" [(ngModel)]="selectedCities1"&gt;&lt;/p-multiSelect&gt;

&lt;p-multiSelect [options]="cities2" [(ngModel)]="selectedCities2" optionLabel="name"&gt;&lt;/p-multiSelect&gt;
</app-code>

<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
import &#123;SelectItem&#125; from 'primeng/api';

interface City &#123;
    name: string,
    code: string
&#125;

export class MyModel &#123;

    cities1: SelectItem[];

    cities2: City[];

    selectedCities1: City[];

    selectedCities2: City[];

    constructor() &#123;
        //SelectItem API with label-value pairs
        this.cities1 = [
            &#123;label:'New York', value:&#123;id:1, name: 'New York', code: 'NY'&#125;&#125;,
            &#123;label:'Rome', value:&#123;id:2, name: 'Rome', code: 'RM'&#125;&#125;,
            &#123;label:'London', value:&#123;id:3, name: 'London', code: 'LDN'&#125;&#125;,
            &#123;label:'Istanbul', value:&#123;id:4, name: 'Istanbul', code: 'IST'&#125;&#125;,
            &#123;label:'Paris', value:&#123;id:5, name: 'Paris', code: 'PRS'&#125;&#125;
        ];

        //An array of cities
        this.cities2 = [
            &#123;name: 'New York', code: 'NY'&#125;,
            &#123;name: 'Rome', code: 'RM'&#125;,
            &#123;name: 'London', code: 'LDN'&#125;,
            &#123;name: 'Istanbul', code: 'IST'&#125;,
            &#123;name: 'Paris', code: 'PRS'&#125;
        ];
    &#125;

&#125;
</app-code>

            <h5>Model Driven Forms</h5>
            <p>MultiSelect can be used in a model driven form as well.</p>
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-multiSelect [options]="cities" formControlName="selectedCities"&gt;&lt;/p-multiSelect&gt;
</app-code>

            <h5>Disabled Options</h5>
            <p>Particular options can be prevented from selection using the <i>disabled</i> property of SelectItem API.</p>

            <h5>Templating</h5>
            <p>Label of a selectitem is displayed by default next to the checkbox in the overlay panel and it is possible to customize
            the content using templating. The ngTemplate receives the selectitem as the implicit variable.</p>

            <p>In addition selectedItems template can be used to customize the selected values display instead of the default comma separated list.</p>
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-multiSelect [options]="cars" [(ngModel)]="selectedCars2"&gt;
    &lt;ng-template let-selectedCars pTemplate="selectedItems"&gt;
        &lt;span *ngFor="let selectedCar of selectedCars"&gt;&#123;&#123;car.brand&#125;&#125;&lt;/span&gt;
    &lt;/ng-template&gt;
    &lt;ng-template let-car let-i="index" pTemplate="item"&gt;
        {{i}}
        &lt;img src="assets/showcase/images/demo/car/&#123;&#123;car.label&#125;&#125;.png" style="width:24px;display:inline-block;vertical-align:middle"/&gt;
        &lt;div style="font-size:14px;float:right;margin-top:4px"&gt;&#123;&#123;car.label&#125;&#125;&lt;/div&gt;
    &lt;/ng-template&gt;
&lt;/p-multiSelect&gt;
&lt;p&gt;Selected Cars: &#123;&#123;selectedCars2&#125;&#125;&lt;/p&gt;
</app-code>

            <h5>Filtering</h5>
            <p>Options can be filtered using an input field in the overlay by enabling the <i>filter</i> property. By default filtering is done against
                label of the SelectItem and filterBy property is available to choose one or more properties of the SelectItem API.</p>
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-multiSelect [options]="cities" [(ngModel)]="selectedCities" [filter]="true"&gt;&lt;/p-multiSelect&gt;
&lt;p-multiSelect [options]="cities" [(ngModel)]="selectedCities" [filter]="true" filterBy="label,value.name"&gt;&lt;/p-multiSelect&gt;
</app-code>

            <h5>Change Detection</h5>
            <p>MultiSelect detects changes to options and selected values using setters so when changing your model,
                prefer creating a new array reference instead of manipulating an existing array.</p>

            <h5>Header and Footer</h5>
            <p><i>p-header</i> and <i>p-footer</i> elements can be used display custom content inside the header and footer sections.</p>
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-multiSelect [options]="cities" formControlName="selectedCities"&gt;
    &lt;p-header&gt;
        //Header content
    &lt;/p-header&gt;
    &lt;p-footer&gt;
        //Footer content
    &lt;/p-footer&gt;
&lt;/p-multiSelect&gt;
</app-code>

            <h5>Virtual Scrolling</h5>
            <p>VirtualScrolling is an efficient way of rendering the options by displaying a small subset of data in the viewport at any time. When dealing with huge number of options, it is suggested to enable VirtualScrolling
                to avoid performance issues. Usage is simple as setting <i>virtualScroll</i> property to true and defining itemSize to specify the height of an item.</p>
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-multiSelect [options]="cities" formControlName="selectedCities" [virtualScroll]="true" itemSize="30"&gt;&lt;/p-multiSelect&gt;
</app-code>

            <h5>Animation Configuration</h5>
            <p>Transition of the open and hide animations can be customized using the showTransitionOptions and hideTransitionOptions properties,
                example below disables the animations altogether.</p>
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-multiSelect [options]="cities" formControlName="selectedCities" [showTransitionOptions]="'0ms'" [hideTransitionOptions]="'0ms'"&gt;&lt;/p-multiSelect&gt;
</app-code>

            <h5>Properties</h5>
            <div class="doc-tablewrapper">
                <table class="doc-table">
                    <thead>
                    <tr>
                        <th>Name</th>
                        <th>Type</th>
                        <th>Default</th>
                        <th>Description</th>
                    </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>options</td>
                            <td>array</td>
                            <td>null</td>
                            <td>An array of objects to display as the available options.</td>
                        </tr>
                        <tr>
                            <td>optionLabel</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Name of the label field of an option when an arbitrary objects instead of SelectItems are used as options.</td>
                        </tr>
                        <tr>
                            <td>disabled</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>When present, it specifies that the element should be disabled.</td>
                        </tr>
                        <tr>
                            <td>readonly</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>When present, it specifies that the component cannot be edited.</td>
                        </tr>
                        <tr>
                            <td>filter</td>
                            <td>boolean</td>
                            <td>true</td>
                            <td>When specified, displays an input field to filter the items on keyup.</td>
                        </tr>
                        <tr>
                            <td>filterBy</td>
                            <td>string</td>
                            <td>label</td>
                            <td>When filtering is enabled, filterBy decides which field or fields (comma separated) to search against.</td>
                        </tr>
                        <tr>
                            <td>filterPlaceHolder</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Defines placeholder of the filter input.</td>
                        </tr>
                        <tr>
                            <td>filterMatchMode</td>
                            <td>string</td>
                            <td>contains</td>
                            <td>Defines how the items are filtered, valid values are "contains" (default) "startsWith", "endsWith", "equals", "notEquals", "in", "lt", "lte", "gt" and "gte".</td>
                        </tr>
                        <tr>
                            <td>filterLocale</td>
                            <td>string</td>
                            <td>undefined</td>
                            <td>Locale to use in filtering. The default locale is the host environment's current locale.</td>
                        </tr>
                        <tr>
                            <td>defaultLabel</td>
                            <td>string</td>
                            <td>Choose</td>
                            <td>Label to display when there are no selections. Deprecated: Use placeholder instead.</td>
                        </tr>
                        <tr>
                            <td>placeholder</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Label to display when there are no selections.</td>
                        </tr>
                        <tr>
                            <td>appendTo</td>
                            <td>any</td>
                            <td>null</td>
                            <td>Target element to attach the overlay, valid values are "body" or a local ng-template variable of another element (note: use binding with brackets for template variables, e.g. [appendTo]="mydiv" for a div element having #mydiv as variable name).</td>
                        </tr>
                        <tr>
                            <td>style</td>
                            <td>object</td>
                            <td>null</td>
                            <td>Inline style of the element.</td>
                        </tr>
                        <tr>
                            <td>styleClass</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Style class of the element.</td>
                        </tr>
                        <tr>
                            <td>panelStyle</td>
                            <td>object</td>
                            <td>null</td>
                            <td>Inline style of the overlay panel.</td>
                        </tr>
                        <tr>
                            <td>scrollHeight</td>
                            <td>string</td>
                            <td>200px</td>
                            <td>Height of the viewport in pixels, a scrollbar is defined if height of list exceeds this value.</td>
                        </tr>
                        <tr>
                            <td>overlayVisible</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>Specifies the visibility of the options panel.</td>
                        </tr>
                        <tr>
                            <td>tabindex</td>
                            <td>number</td>
                            <td>null</td>
                            <td>Index of the element in tabbing order.</td>
                        </tr>
                        <tr>
                            <td>dataKey</td>
                            <td>string</td>
                            <td>null</td>
                            <td>A property to uniquely identify a value in options.</td>
                        </tr>
                        <tr>
                            <td>name</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Name of the input element.</td>
                        </tr>
                        <tr>
                            <td>ariaLabelledBy</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Establishes relationships between the component and label(s) where its value should be one or more element IDs.</td>
                        </tr>
                        <tr>
                            <td>inputId</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Identifier of the focus input to match a label defined for the component.</td>
                        </tr>
                        <tr>
                            <td>displaySelectedLabel</td>
                            <td>boolean</td>
                            <td>true</td>
                            <td>Whether to show labels of selected item labels or use default label.</td>
                        </tr>
                        <tr>
                            <td>maxSelectedLabels</td>
                            <td>number</td>
                            <td>3</td>
                            <td>Decides how many selected item labels to show at most.</td>
                        </tr>
                        <tr>
                            <td>selectedItemsLabel</td>
                            <td>string</td>
                            <td>&#123;0&#125; items selected</td>
                            <td>Label to display after exceeding max selected labels.</td>
                        </tr>
                        <tr>
                            <td>showToggleAll</td>
                            <td>boolean</td>
                            <td>true</td>
                            <td>Whether to show the checkbox at header to toggle all items at once.</td>
                        </tr>
                        <tr>
                            <td>resetFilterOnHide</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>Clears the filter value when hiding the dropdown.</td>
                        </tr>
                        <tr>
                            <td>dropdownIcon</td>
                            <td>string</td>
                            <td>pi pi-chevron-down</td>
                            <td>Icon class of the dropdown icon.</td>
                        </tr>
                        <tr>
                            <td>emptyFilterMessage</td>
                            <td>string</td>
                            <td>No results found</td>
                            <td>Text to display when filtering does not return any results.</td>
                        </tr>
                        <tr>
                            <td>showHeader</td>
                            <td>boolean</td>
                            <td>true</td>
                            <td>Whether to show the header.</td>
                        </tr>
                        <tr>
                            <td>selectionLimit</td>
                            <td>number</td>
                            <td>null</td>
                            <td>Number of maximum options that can be selected.</td>
                        </tr>
                        <tr>
                            <td>baseZIndex</td>
                            <td>number</td>
                            <td>0</td>
                            <td>Base zIndex value to use in layering.</td>
                        </tr>
                        <tr>
                            <td>autoZIndex</td>
                            <td>boolean</td>
                            <td>true</td>
                            <td>Whether to automatically manage layering.</td>
                        </tr>
                        <tr>
                            <td>showTransitionOptions</td>
                            <td>string</td>
                            <td>.12s cubic-bezier(0, 0, 0.2, 1)</td>
                            <td>Transition options of the show animation.</td>
                        </tr>
                        <tr>
                            <td>hideTransitionOptions</td>
                            <td>string</td>
                            <td>.1s linear</td>
                            <td>Transition options of the hide animation.</td>
                        </tr>
                        <tr>
                            <td>itemSize</td>
                            <td>number</td>
                            <td>null</td>
                            <td>Height of an item in the list for VirtualScrolling.</td>
                        </tr>
                        <tr>
                            <td>virtualScroll</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>Whether the data should be loaded on demand during scroll.</td>
                        </tr>
                        <tr>
                            <td>ariaFilterLabel</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Defines a string that labels the filter input.</td>
                        </tr>
                        <tr>
                            <td>tooltip</td>
                            <td>any</td>
                            <td>null</td>
                            <td>Advisory information to display in a tooltip on hover.</td>
                        </tr>
                        <tr>
                            <td>tooltipStyleClass</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Style class of the tooltip.</td>
                        </tr>
                        <tr>
                            <td>tooltipPosition</td>
                            <td>string</td>
                            <td>top</td>
                            <td>Position of the tooltip, valid values are right, left, top and bottom.</td>
                        </tr>
                        <tr>
                            <td>tooltipPositionStyle</td>
                            <td>string</td>
                            <td>absolute</td>
                            <td>Type of CSS position.</td>
                        </tr>
                        <tr>
                            <td>autofocusFilter</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>Applies focus to the filter element when the overlay is shown.</td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <h5>Events</h5>
            <div class="doc-tablewrapper">
                <table class="doc-table">
                    <thead>
                    <tr>
                        <th>Name</th>
                        <th>Parameters</th>
                        <th>Description</th>
                    </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>onClick</td>
                            <td>event: Click event</td>
                            <td>Callback to invoke when component is clicked.</td>
                        </tr>
                        <tr>
                            <td>onChange</td>
                            <td>event.originalEvent: browser event<br />
                                event.value: Current selected values<br />
                                event.itemValue: Toggled item value
                            </td>
                            <td>Callback to invoke when value changes.</td>
                        </tr>
                        <tr>
                            <td>onFocus</td>
                            <td>event.originalEvent: browser event</td>
                            <td>Callback to invoke when multiselect receives focus.</td>
                        </tr>
                        <tr>
                            <td>onBlur</td>
                            <td>event.originalEvent: browser event</td>
                            <td>Callback to invoke when multiselect loses focus.</td>
                        </tr>
                        <tr>
                            <td>onPanelShow</td>
                            <td>-</td>
                            <td>Callback to invoke when overlay panel becomes visible.</td>
                        </tr>
                        <tr>
                            <td>onPanelHide</td>
                            <td>-</td>
                            <td>Callback to invoke when overlay panel becomes hidden.</td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <h5>Styling</h5>
            <p>Following is the list of structural style classes, for theming classes visit <a href="#" [routerLink]="['/theming']">theming page</a>.</p>
            <div class="doc-tablewrapper">
                <table class="doc-table">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Element</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>p-multiselect</td>
                            <td>Container element.</td>
                        </tr>
                        <tr>
                            <td>p-multiselect-label-container</td>
                            <td>Container of the label to display selected items.</td>
                        </tr>
                        <tr>
                            <td>p-multiselect-label</td>
                            <td>Label to display selected items.</td>
                        </tr>
                        <tr>
                            <td>p-multiselect-trigger</td>
                            <td>Dropdown button.</td>
                        </tr>
                        <tr>
                            <td>p-multiselect-filter-container</td>
                            <td>Container of filter input.</td>
                        </tr>
                        <tr>
                            <td>p-multiselect-panel</td>
                            <td>Overlay panel for items.</td>
                        </tr>
                        <tr>
                            <td>p-multiselect-items</td>
                            <td>List container of items.</td>
                        </tr>
                        <tr>
                            <td>p-multiselect-item</td>
                            <td>An item in the list.</td>
                        </tr>
                        <tr>
                            <td>p-multiselect-open</td>
                            <td>Container element when overlay is visible.</td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <h5>Dependencies</h5>
            <p>Angular CDK.</p>
        </p-tabPanel>

        <p-tabPanel header="Source">
            <a href="https://github.com/primefaces/primeng/tree/master/src/app/showcase/components/multiselect" class="btn-viewsource" target="_blank">
                <span>View on GitHub</span>
            </a>
            <a href="https://stackblitz.com/edit/primeng-multiselect-demo" class="btn-viewsource" style="margin-left: .5em;" target="_blank">
                <span>Edit in StackBlitz</span>
            </a>
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;h5&gt;Basic&lt;/h5&gt;
&lt;p-multiSelect [options]="cities" [(ngModel)]="selectedCities" defaultLabel="Select a City" optionLabel="name"&gt;&lt;/p-multiSelect&gt;

&lt;h5&gt;Templating&lt;/h5&gt;
&lt;p-multiSelect [options]="countries" [(ngModel)]="selectedCountries1" defaultLabel="Select a Country" optionLabel="name" class="multiselect-custom"&gt;
    &lt;ng-template let-value pTemplate="selectedItems"&gt;
        &lt;div class="country-item country-item-value" *ngFor="let option of selectedCountries1"&gt;
            &lt;img src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + option.code.toLowerCase()" /&gt;
            &lt;div&gt;&#123;&#123;option.name&#125;&#125;&lt;/div&gt;
        &lt;/div&gt;
        &lt;div *ngIf="!selectedCountries1 || selectedCountries1.length === 0" class="country-placeholder"&gt;
            Select Countries
        &lt;/div&gt;
    &lt;/ng-template&gt;
    &lt;ng-template let-country pTemplate="item"&gt;
        &lt;div class="country-item"&gt;
            &lt;img src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + country.value.code.toLowerCase()" /&gt;
            &lt;div&gt;&#123;&#123;country.value.name&#125;&#125;&lt;/div&gt;
        &lt;/div&gt;
    &lt;/ng-template&gt;
&lt;/p-multiSelect&gt;

&lt;h5&gt;Virtual Scroll (10000 Items)&lt;/h5&gt;
&lt;p-multiSelect [options]="items" [showToggleAll]="false" [(ngModel)]="selectedCountries2" optionLabel="name" [virtualScroll]="true" [filter]="true" [itemSize]="34" class="multiselect-custom-virtual-scroll"&gt;
    &lt;ng-template let-country pTemplate="item"&gt;
        &lt;div class="country-item"&gt;
            &lt;img src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + country.value.code.toLowerCase()" /&gt;
            &lt;div&gt;&#123;&#123;country.value.name&#125;&#125;&lt;/div&gt;
        &lt;/div&gt;
    &lt;/ng-template&gt;
&lt;/p-multiSelect&gt;
</app-code>

<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
export class MultiSelectDemo &#123;

    selectedCities: string[] = [];
    
    selectedCountries1: string[] = [];

    selectedCountries2: string[] = [];

    items: SelectItem[];

    item: string;

    cities: any[];

    countries: any[];

    constructor(private countryService: CountryService) &#123;
        
        this.items = [];

        this.countryService.getCountries().then(countries => &#123;
            this.items = countries;
        &#125;);

        this.countries = [
            &#123;name: 'Australia', code: 'AU'&#125;,
            &#123;name: 'Brazil', code: 'BR'&#125;,
            &#123;name: 'China', code: 'CN'&#125;,
            &#123;name: 'Egypt', code: 'EG'&#125;,
            &#123;name: 'France', code: 'FR'&#125;,
            &#123;name: 'Germany', code: 'DE'&#125;,
            &#123;name: 'India', code: 'IN'&#125;,
            &#123;name: 'Japan', code: 'JP'&#125;,
            &#123;name: 'Spain', code: 'ES'&#125;,
            &#123;name: 'United States', code: 'US'&#125;
        ];

        this.cities = [
            &#123;name: 'New York', code: 'NY'&#125;,
            &#123;name: 'Rome', code: 'RM'&#125;,
            &#123;name: 'London', code: 'LDN'&#125;,
            &#123;name: 'Istanbul', code: 'IST'&#125;,
            &#123;name: 'Paris', code: 'PRS'&#125;
        ];
    &#125;
&#125;
</app-code>
<app-code lang="css" ngNonBindable ngPreserveWhitespaces>
    :host ::ng-deep .p-multiselect &#123;
        min-width: 15rem;
    &#125;
    
    :host ::ng-deep .multiselect-custom-virtual-scroll .p-multiselect &#123;
        min-width: 20rem;
    &#125;
    
    :host ::ng-deep .multiselect-custom &#123;
        .p-multiselect-label &#123;
            padding-top: .25rem;
            padding-bottom: .25rem;
        &#125;
    
        .country-item-value &#123;
            padding: .25rem .5rem;
            border-radius: 3px;
            display: inline-flex;
            margin-right: .5rem;
            background-color: var(--primary-color);
            color: var(--primary-color-text);
    
            img.flag &#123;
                width: 17px;
            &#125;
        &#125;
    
        .country-placeholder &#123;
            padding: 0.25rem;
        &#125;
    &#125;
</app-code>
<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
@Injectable()
export class CountryService &#123;

    constructor(private http: Http) &#123;&#125;

    getCountries() &#123;
        return this.http.get('showcase/resources/data/countries.json')
                    .toPromise()
                    .then(res => &lt;any[]&gt; res.json().data)
                    .then(data => &#123; return data; &#125;);
    &#125;
&#125;
</app-code>
        </p-tabPanel>
        <p-tabPanel header="StackBlitz">
            <ng-template pTemplate="content">
                <iframe src="https://stackblitz.com/edit/primeng-multiselect-demo?embed=1" style="width: 100%; height: 768px; border: none;"></iframe>
            </ng-template>
        </p-tabPanel>
    </p-tabView>
</div>
